package de.teamgamma.cansat.groundstation.control;


import org.json.JSONObject;

import de.szut.gui.options.Options;
import de.teamgamma.cansat.groundstation.livestream.LivestreamPanel;
import de.teamgamma.cansat.groundstation.options.OptionKeys;
import de.teamgamma.cansat.groundstation.server.Server;
import de.teamgamma.cansat.groundstation.usb.USB;

/**
 * Controller class that controls the software
 * @author Marc Huisinga
 *
 */

public class Controller {
	private GUIController guiController;
	private Options options;
	private Thread serverThread;
	private Thread usbThread;
	private static Controller instance;

	/**
	 * Gets the instance of the controller
	 * @return instance of the controller
	 */
	public static Controller getInstance() {
		if (instance == null) {
			instance = new Controller();
			instance.startOptions();
			instance.startUSB();
			instance.startServer();
			instance.startGUI();
		}
		return instance;
	}
	
	/**
	 * Main of the program, starts up the program
	 * @param args - console arguments
	 */
	public static void main(String[] args) {
		getInstance();
	}
	
	private Controller() {}
	
	/**
	 * Notifies the livestream with a new JSONObject
	 * @param json JSONObject to notify with
	 */
	public void update(JSONObject json) {
		try {
			LivestreamPanel panel = (LivestreamPanel) guiController.getMainFrame().getContentPane();
			panel.getStream().update(json);
		} catch (ClassCastException e) {
			System.err.println("Livestream is not open!");
		}
	}
	
	private void startOptions() {
		options = new Options();
		options.loadOptionsFromKeys(OptionKeys.ALLKEYS);
	}
	
	private void startGUI() {
		guiController = new GUIController();
		guiController.startGUI();
	}
	
	private void startServer() {
		serverThread = new Thread(new Server());
		serverThread.start();
	}
	
	private void startUSB() {
		usbThread = new Thread(new USB());
		usbThread.start();
	}
	
	/**
	 * Gets the GUI-Controller of the program
	 * @return GUI-Controller
	 */
	public GUIController getGuiController() {
		return guiController;
	}

	/**
	 * Sets the GUI-Controller of the program
	 * @param guiController - GUI-Controller
	 */
	public void setGuiController(GUIController guiController) {
		this.guiController = guiController;
	}

	/**
	 * Gets the main options of the program
	 * @return options
	 */
	public Options getOptions() {
		return options;
	}

	/**
	 * Sets the main options of the program
	 * @param options
	 */
	public void setOptions(Options options) {
		this.options = options;
	}
}
